package com.ctsi.security.service;

import com.ctsi.commons.util.UtilValidate;
import com.ctsi.commons.util.response.Page;
import com.ctsi.framework.mybatis.support.MybatisGenericDao;
import com.ctsi.security.ISecurity;
import com.ctsi.security.domain.DataObject;
import com.ctsi.security.domain.RoleDataObject;
import com.ctsi.security.manager.impl.SecurityImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.*;

/**
 * 实现对数据对象表的CRUD
 * 
 * @author zhangjw
 * 
 */
@Repository
public class DataObjectService {
	private static final Logger logger = LoggerFactory.getLogger(DataObjectService.class);
	@Autowired
	private MybatisGenericDao dao ;
	private RoleSecurityService roleSecurityService;
    @Autowired
	private ISecurity security;

	/**
	 * 保存数据对象
	 * 
	 * @param dataObject
	 */
	public void saveDataObject(DataObject dataObject) {
		if (dataObject != null) {
			String id = dataObject.getId();
			if (UtilValidate.isEmpty(id)) {
				dataObject.setId(UUID.randomUUID().toString());
			}
			SecurityImpl.clearDataObjectCache(dataObject.getDataObjectTypeId());
			dao.insert(dataObject);
		}
	}

	/**
	 * 修改数据对象
	 * 
	 * @param dataObject
	 */
	public void updateDataObject(DataObject dataObject) {
		if (dataObject != null) {
			SecurityImpl.clearDataObjectCache(dataObject.getDataObjectTypeId());
			dao.update(dataObject);
		}
	}

	/**
	 * 删除数据对象
	 * 
	 * @param id
	 */
	public void removeDataObject(String id, String dataObjectId) {
		if (UtilValidate.isEmpty(id)) {
			return;
		}
		DataObject dataObject = this.findById(id);
		SecurityImpl.clearDataObjectCache(dataObject.getDataObjectTypeId());

		dao.remove(dataObject);
		// dao.removeObject(com.gentlesoft.security.domain.DataObject.class,
		// id);
		// 删除角色数据对象表中相应的记录
		List<RoleDataObject> listRoleDataObject = roleSecurityService.findRoleDataObject(new String[] { "dataObjectId" }, new Object[] { dataObject.getDataObjectId() });
		for (RoleDataObject roleDataObject : listRoleDataObject) {
			roleSecurityService.removeRoleDataObject(roleDataObject.getId(), roleDataObject.getDataObjectTypeId());
		}
		List<DataObject> list = roleSecurityService.queryInnerDataObject(dataObject.getDataObjectTypeId(), dataObject.getDataObjectId());
		for (DataObject dat : list) {
			removeDataObject(dat);
		}

	}

	public void removeDataObject(DataObject dataObject) {
		SecurityImpl.clearDataObjectCache(dataObject.getDataObjectTypeId());
		dao.remove(dataObject);
		List<RoleDataObject> listRoleDataObject = roleSecurityService.findRoleDataObject(new String[] { "dataObjectId" }, new Object[] { dataObject.getDataObjectId() });
		for (RoleDataObject roleDataObject : listRoleDataObject) {
			roleSecurityService.removeRoleDataObject(roleDataObject.getId(), roleDataObject.getDataObjectTypeId());
		}
		List<DataObject> list = roleSecurityService.queryInnerDataObject(dataObject.getDataObjectTypeId(), dataObject.getDataObjectId());
		for (DataObject dat : list) {
			removeDataObject(dat);
		}
	}

	/**
	 * 查看全部数据对象
	 * 
	 * @return
	 */
	public List<DataObject> findDataObjectAll() {
		return dao.find(DataObject.class, (Map<String, Object>) null);

	}

	/**
	 * 条件查询数据
	 * 
	 * @param field
	 * @param args
	 * @return
	 */
	public List<DataObject> findDataObject(String[] field, Object[] args) {

		if (field == null || args == null) {
			logger.warn("field or args is null");
			return new ArrayList<DataObject>(0);
		}
		if (field.length != args.length) {
			logger.warn("field's length not equal args's length!");
			return new ArrayList<DataObject>(0);
		}
		Map<String, Object> params = new HashMap<String, Object>();
		for (int i = 0; i < field.length; i++) {
			params.put(field[i].toLowerCase(), args[i]);
		}
		return dao.find(DataObject.class, params);

	}

	public DataObject findByDataObjectId(String id) {
		List<DataObject> listDataObject = findDataObject(new String[] { "dataobjectid" }, new Object[] { id });
		DataObject dataObject = null;
		if (listDataObject.size() > 0) {
			dataObject = listDataObject.get(0);
		} else {
			dataObject = new DataObject();
		}
		return dataObject;
	}

	public DataObject findById(String id) {
		List<DataObject> listDataObject = findDataObject(new String[] { "id" }, new Object[] { id });
		DataObject dataObject = null;
		if (listDataObject.size() > 0) {
			dataObject = listDataObject.get(0);
		} else {
			dataObject = new DataObject();
		}
		return dataObject;
	}

	/**
	 * 查询数据对象
	 * 
	 * @param pageSize
	 * @param startIndex
	 * @return
	 */
	private Page<Map<String, Object>> queryDataObject(int pageSize, int startIndex) {
		Page<Map<String, Object>> result = dao.queryPage(DataObject.class.getName() + ".queryForPage", Collections.EMPTY_MAP, startIndex, pageSize);
		convert(result);
		return result;
	}

	private void convert(Page<Map<String, Object>> result) {
		List<Map<String, Object>> pageList = result.getResult();
		for (Map<String, Object> listItem : pageList) {
			String id = (String) listItem.get("ID");
			String dataObjectId = (String) listItem.get("DATAOBJECTID");
			String dataObjectName = (String) listItem.get("DATAOBJECTNAME");
			String description = (String) listItem.get("DESCRIPTION");
			String dataObjectTypeId = (String) listItem.get("DATAOBJECTTYPEID");
			String dataObjectTypeName = (String) listItem.get("DATAOBJECTTYPENAME");
			if (id != null) {
				listItem.remove("ID");
				listItem.put("id", id);
			}
			if (dataObjectId != null) {
				listItem.remove("DATAOBJECTID");
				listItem.put("dataObjectId", dataObjectId);
			}
			if (dataObjectName != null) {
				listItem.remove("DATAOBJECTNAME");
				listItem.put("dataObjectName", dataObjectName);
			}
			if (description != null) {
				listItem.remove("DESCRIPTION");
				listItem.put("description", description);
			}
			if (dataObjectTypeId != null) {
				listItem.remove("DATAOBJECTTYPEID");
				listItem.put("dataObjectTypeId", dataObjectTypeId);
			}
			if (dataObjectTypeName != null) {
				listItem.remove("DATAOBJECTTYPENAME");
				listItem.put("dataObjectTypeName", dataObjectTypeName);
			}
		}
	}

	/**
	 * 带数据权限的查询数据对象
	 * 
	 * @param userLogin
	 * @param dataObjectType
	 * @param pageSize
	 * @param startIndex
	 * @return
	 */
	public Page<Map<String, Object>> queryDataObject(String userLogin, String dataObjectType, String action, int pageSize, int startIndex) {
		Page<Map<String, Object>> result = new Page<Map<String, Object>>();
		// 判断是否需要控制数据权限
		if (!security.isControl(userLogin, dataObjectType, action)) {
			// 不需要控制数据权限
			logger.info("查询数据对象不控制数据权限");
			result = queryDataObject(pageSize, startIndex);
		} else {
			// TODO 这里的数据权限控制有问题，需要更改的数据结构，先不控制数据权限
			result = queryDataObject(pageSize, startIndex);
		}
		return result;
	}

	/**
	 * 查找某一类型的数据对象
	 * 
	 * @param pageSize
	 * @param startIndex
	 * @param dataObjectTypeId
	 * @return
	 */
	public Page<DataObject> queryDataObject(int pageSize, int startIndex, String dataObjectTypeId) {

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("dataobjecttypeid", dataObjectTypeId);
		return queryDataObject(pageSize, startIndex, params);
	}

	/**
	 * 根据数据权限的数据权限查询当前用户的数据权限id wangbf add on 2011-10-13
	 * 
	 * @param userLogin
	 * @param dataObjectType
	 * @param action
	 * @param pageSize
	 * @param startIndex
	 * @param params
	 * @return
	 */
	public Page<DataObject> queryDataObject(String userLogin, String dataObjectType, String action, int pageSize, int startIndex, Map<String, Object> params) {
		if (!security.isControl(userLogin, dataObjectType, action))
			return queryDataObject(pageSize, startIndex, params);
		else {
			List<String> items = security.getDataObjectIds(userLogin, dataObjectType, action);
			logger.info("数据对象为{}", items);
			if (items != null && items.size() > 0) {
				params.put("sysDataObjectids", items);
				return queryDataObject(pageSize, startIndex, params);
			}
		}
		return new Page();
	}

	public Page<DataObject> queryDataObject(int pageSize, int startIndex, Map<String, Object> params) {
		if (params == null) {
			params = new HashMap<String, Object>();
		}
		if (pageSize == -1) {
			List<DataObject> list = (List<DataObject>)dao.queryForList(DataObject.class.getName() + ".selectByMap", params);
			if (list != null)
				return new Page<DataObject>(list, list.size());
			else
				return new Page<DataObject>();
		} else {
			return dao.queryPage(DataObject.class.getName() + ".selectByMap", params, startIndex, pageSize);
		}
	}

	public Page<DataObject> queryDataObjectAll(int pageSize, int startIndex, Map<String, Object> params) {
		if (params == null) {
			params = new HashMap<String, Object>();
		}
		if (pageSize == -1) {
			List<DataObject> list = (List<DataObject>)dao.queryForList(DataObject.class.getName() + ".selectByMapAll", params);
			if (list != null)
				return new Page<DataObject>(list, list.size());
			else
				return new Page<DataObject>();
		} else {
			return dao.queryPage(DataObject.class.getName() + ".selectByMapAll", params, startIndex, pageSize);
		}
	}
	/**
	 * 带数据权限的分页查询 zhangjw 2012-03-14
	 * @param userlogin
	 * @param dataObjectType
	 * @param action
	 * @param params
	 * @param per ->if true query all
	 * @return
	 */
	public Page<DataObject> queryDataObjectWithDataPermission(String userlogin,String dataObjectType,String action,Map<String,Object> params,int pageSize, int startIndex,boolean per){
		if(!security.isControl(userlogin,dataObjectType, action)){
			
			if(per){
				  return queryDataObjectAll(pageSize, startIndex, params);
			}else{
				  return queryDataObject(pageSize,startIndex, params);
			}
			
		}else{
			List<String> dataObjectIds=security.getDataObjectIds(userlogin, dataObjectType, action);
			if(UtilValidate.isEmpty(dataObjectIds)){
			    return new Page<DataObject>();
			}else{
				params.put("sysDataObjectids", dataObjectIds);
				if(per){
					  return queryDataObjectAll(pageSize, startIndex, params);
				}
				else
				{
					  return queryDataObject(pageSize,startIndex, params);
				}
			}
		}
		
	}

	public boolean valDataObjectId(String dataObjectId) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("dataobjectid", dataObjectId);
		List<DataObject> temp = dao.find(DataObject.class, params);
		if (temp.size() > 0) {
			return true;
		} else {
			return false;
		}

	}

	public Long getMaxOrderNo() {
		Long result = (Long) dao.queryForObject(DataObject.class.getName() + ".selectMaxOrderNo");
		if (null == result) {
			return 0L;
		}
		return result;
	}

	public RoleSecurityService getRoleSecurityService() {
		return roleSecurityService;
	}

	public void setRoleSecurityService(RoleSecurityService roleSecurityService) {
		this.roleSecurityService = roleSecurityService;
	}

	public void setdao(MybatisGenericDao dao) {
		this.dao = dao;
	}

	public MybatisGenericDao getdao() {
		return dao;
	}
}
